﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Text;
using System.Windows.Forms;

namespace QLFUI
{
    public partial class FormBase : Form
    {
        #region 变量

        private Color borderColor = Color.FromArgb(20, 0, 0, 0);
        private Color innerBorderColor = Color.FromArgb(75, 240, 240, 240);

        private Color titleBackColorStart = Color.FromArgb(238, 241, 243);
        private Color titleBackColorEnd = Color.FromArgb(225, 230, 235);

        private Color contentTopBorderColor = Color.FromArgb(186, 197, 207);
        private Color contentBottomBorderColor = Color.Transparent;
        private Color contentBackColorStart = Color.FromArgb(238, 241, 243);
        private Color contentBackColorEnd = Color.FromArgb(225, 230, 235);

        private Color footerBackColorStart = Color.FromArgb(238, 241, 243);
        private Color footerBackColorEnd = Color.FromArgb(225, 230, 235);

        private Rectangle titleRectangle;
        private Rectangle contentRectangle;
        private Rectangle footerRectangle;

        private BorderRadiu currentBorderRadiu = new BorderRadiu();

        private int titleHeight = 25;
        private int footerHeight = 30;

        private bool showCloseButton = true;
        private bool sizeAble = true;
        private bool canMove = true;

        private int transparentAlpha = 125;

        /// <summary>
        /// 用于开启透明效果时所有的图像都画在
        /// 这个图片上
        /// </summary>
        protected static Bitmap currentBitmap;

        /// <summary>
        /// 最大化之前记录普通状态下的窗口位置
        /// </summary>
        private Rectangle rectangleBeforeMax = new Rectangle();
        private FormWindowState currentFormWindowState = FormWindowState.Normal;

        //功能按钮（关闭，最小化，最大化）的右边距
        private int functionBtnMarginRight = 8;
        private int functionBtnMarginTop = 0;

        private FormHideenResize frmResize;
        #endregion

        #region - 属性 -

        public static Graphics GetNewGraphics
        {
            get { return Graphics.FromImage(currentBitmap); }
        }

        public new FormWindowState WindowState
        {
            get { return currentFormWindowState; }
            set
            {
                currentFormWindowState = value;
                switch (currentFormWindowState)
                {
                    case FormWindowState.Normal:
                        Size = rectangleBeforeMax.Size;
                        Top = rectangleBeforeMax.Y;
                        Left = rectangleBeforeMax.X;

                        break;

                    case FormWindowState.Maximized:

                        rectangleBeforeMax.X = Left;
                        rectangleBeforeMax.Y = Top;
                        rectangleBeforeMax.Size = Size;

                        Width = Screen.PrimaryScreen.WorkingArea.Width + 4;
                        Height = Screen.PrimaryScreen.WorkingArea.Height + 4;
                        Top = -1;
                        Left = -1;
                        break;

                    case FormWindowState.Minimized:
                        base.WindowState = FormWindowState.Minimized;
                        break;
                }
            }
        }

        /// <summary>
        /// 是否开启透明效果
        /// </summary>
        [Browsable(true), Description("是否开启透明效果"), Category("2_QLFUI_Other")]
        public bool EnableTransparent
        {
            get;
            set;
        }

        /// <summary>
        /// 透明度
        /// </summary>
        [Browsable(true), Description("透明度"), Category("2_QLFUI_Other")]
        public int TransparentAlpha
        {
            get
            {
                if (EnableTransparent)
                {
                    return transparentAlpha;
                }
                return 255; //如果不允许透明，则返回不透明
            }
            set
            {
                transparentAlpha = value;
            }
        }

        /// <summary>
        /// 隐藏FormBorderStyle
        /// </summary>
        [Browsable(false)]
        public new FormBorderStyle FormBorderStyle
        {
            get { return base.FormBorderStyle; }
            set { base.FormBorderStyle = value; }
        }

        /// <summary>
        /// 是否允许调整窗体大小
        /// </summary>
        [Browsable(true), Description("是否允许调整窗体大小"), Category("2_QLFUI_Other")]
        public bool SizeAble
        {
            get { return sizeAble; }
            set { sizeAble = value; }
        }

        /// <summary>
        /// 是否允许鼠标移动窗体
        /// </summary>
        [Browsable(true), Description("是否允许鼠标移动窗体"), Category("2_QLFUI_Other")]
        public bool CanMove
        {
            get { return canMove; }
            set { canMove = value; }
        }

        /// <summary>
        /// 标题栏背景渐变起始颜色
        /// </summary>
        [Browsable(true), Description("标题栏背景渐变起始颜色"), Category("1_QLFUI_UI")]
        public Color TitleBackColorStart
        {
            get { return titleBackColorStart; }
            set { titleBackColorStart = value; Invalidate(); }
        }

        /// <summary>
        /// 标题栏背景渐变结束颜色
        /// </summary>
        [Browsable(true), Description("标题栏背景渐变结束颜色"), Category("1_QLFUI_UI")]
        public Color TitleBackColorEnd
        {
            get { return titleBackColorEnd; }
            set { titleBackColorEnd = value; Invalidate(); }
        }

        /// <summary>
        /// 内容区域外边框颜色
        /// </summary>
        [Browsable(true), Description("内容区域外边框颜色"), Category("1_QLFUI_UI")]
        public Color ContentTopBorderColor
        {
            get { return contentTopBorderColor; }
            set { contentTopBorderColor = value; Invalidate(); }
        }

        /// <summary>
        /// 内容区域内边框颜色
        /// </summary>
        [Browsable(true), Description("内容区域内边框颜色"), Category("1_QLFUI_UI")]
        public Color ContentBottomBorderColor
        {
            get { return contentBottomBorderColor; }
            set { contentBottomBorderColor = value; Invalidate(); }
        }

        /// <summary>
        /// 内容区域背景渐变起始颜色
        /// </summary>
        [Browsable(true), Description("内容区域背景渐变起始颜色"), Category("1_QLFUI_UI")]
        public Color ContentBackColorStart
        {
            get { return contentBackColorStart; }
            set { contentBackColorStart = value; Invalidate(); }
        }

        /// <summary>
        /// 内容区域背景渐变结束颜色
        /// </summary>
        [Browsable(true), Description("内容区域背景渐变结束颜色"), Category("1_QLFUI_UI")]
        public Color ContentBackColorEnd
        {
            get { return contentBackColorEnd; }
            set { contentBackColorEnd = value; Invalidate(); }
        }

        /// <summary>
        /// 底部背景渐变起始颜色
        /// </summary>
        [Browsable(true), Description("底部背景渐变起始颜色"), Category("1_QLFUI_UI")]
        public Color FooterBackColorStart
        {
            get { return footerBackColorStart; }
            set { footerBackColorStart = value; Invalidate(); }
        }

        /// <summary>
        /// 底部背景渐变结束颜色
        /// </summary>
        [Browsable(true), Description("底部背景渐变结束颜色"), Category("1_QLFUI_UI")]
        public Color FooterBackColorEnd
        {
            get { return footerBackColorEnd; }
            set
            {
                footerBackColorEnd = value;
                Invalidate();
            }
        }

        /// <summary>
        /// 标题栏区域
        /// </summary>
        protected Rectangle TitleRectangle
        {
            get
            {

                titleRectangle = ClientRectangle;
                titleRectangle.Height = TitleHeight;

                return titleRectangle;
            }
        }

        /// <summary>
        /// 中间的内容部分
        /// </summary>
        protected Rectangle ContentRectangle
        {
            get
            {
                contentRectangle = ClientRectangle;
                contentRectangle.Y = TitleRectangle.Height;
                contentRectangle.Height = Height - TitleHeight - FooterHeight;

                return contentRectangle;
            }
        }

        /// <summary>
        /// 底部区域
        /// </summary>
        protected Rectangle FooterRectangle
        {
            get
            {
                footerRectangle = ClientRectangle;
                footerRectangle.Y = TitleHeight + ContentRectangle.Height;
                footerRectangle.Height = FooterHeight;

                return footerRectangle;
            }
        }

        /// <summary>
        /// 窗体边框弯曲程度，值越大越弯曲，0为不弯曲
        /// </summary>
        [Category("2_QLFUI_Other"), Description("窗体边框弯曲程度，值越大越弯曲，0为不弯曲")]
        [TypeConverter(typeof(ExpandableObjectConverter))]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public BorderRadiu BorderRadius
        {
            get { return currentBorderRadiu; }
        }

        /// <summary>
        /// 标题栏高度
        /// </summary>
        [Browsable(true), Description("标题栏高度"), Category("2_QLFUI_Other")]
        [RefreshProperties(RefreshProperties.Repaint)]
        public int TitleHeight
        {
            get { return titleHeight; }
            set
            {
                titleHeight = value;
                Invalidate();
            }
        }

        /// <summary>
        /// 底部栏高度
        /// </summary>
        [Browsable(true), Description("底部栏高度"), Category("2_QLFUI_Other")]
        public int FooterHeight
        {
            get { return footerHeight; }
            set
            {
                footerHeight = value;
                Invalidate();
            }
        }

        /// <summary>
        /// 边框颜色
        /// </summary>
        [Browsable(true), Description("边框颜色"), Category("1_QLFUI_UI")]
        public Color BorderColor
        {
            get { return borderColor; }
            set
            {
                borderColor = value;
                Invalidate();
            }
        }

        /// <summary>
        /// 内边框颜色
        /// </summary>
        [Browsable(true), Description("内边框颜色"), Category("1_QLFUI_UI")]
        public Color InnerBorderColor
        {
            get { return innerBorderColor; }
            set
            {
                innerBorderColor = value;
                Invalidate();
            }
        }

        /// <summary>
        /// 是否显示关闭按钮
        /// </summary>
        [Browsable(true), Description("是否显示关闭按钮"), Category("2_QLFUI_Other")]
        public bool ShowCloseButton
        {
            get { return showCloseButton; }
            set
            {
                showCloseButton = value;
                UpdateFunctionButtonLocation();
                Invalidate();
            }

        }

        [Localizable(true)]
        public override Size MaximumSize
        {
            get
            {
                return base.MaximumSize;
            }
            set
            {
                base.MaximumSize = value;
                UpdateFunctionButtonLocation();
                Invalidate();
            }
        }

        [Localizable(true)]
        public override Size MinimumSize
        {
            get
            {
                return base.MinimumSize;
            }
            set
            {
                base.MinimumSize = value;
                UpdateFunctionButtonLocation();
                Invalidate();
            }
        }

        /// <summary>
        /// 功能按钮（最小化，关闭，最大化按钮）距离窗体的右边距
        /// </summary>
        [Browsable(true), Description("功能按钮（最小化，关闭，最大化按钮）距离窗体的右边距"), Category("2_QLFUI_Other")]
        public int FunctionBtnMarginRight
        {
            get { return functionBtnMarginRight; }
            set
            {
                functionBtnMarginRight = value;
                UpdateFunctionButtonLocation();
                Invalidate();
            }
        }

        /// <summary>
        /// 功能按钮（最小化，关闭，最大化按钮）距离窗体的上边距
        /// </summary>
        [Browsable(true), Description("功能按钮（最小化，关闭，最大化按钮）距离窗体的上边距"), Category("2_QLFUI_Other")]
        public int FunctionBtnMarginTop
        {
            get { return functionBtnMarginTop; }
            set
            {
                functionBtnMarginTop = value;
                UpdateFunctionButtonLocation();
                Invalidate();
            }
        }

        #endregion

        #region - 构造函数 -

        public FormBase()
        {
            SetStyle(
                ControlStyles.OptimizedDoubleBuffer |
                ControlStyles.UserPaint |
                ControlStyles.ResizeRedraw|
                ControlStyles.AllPaintingInWmPaint, true);

            InitializeComponent();

            btnMin.Paint += btnMin_Paint;
            btnMax.Paint += btnMax_Paint;
            btnClose.Paint += btnClose_Paint;
            btnClose.Click += btnClose_Click;
            btnMin.Click += btnMin_Click;
            btnMax.Click += btnMax_Click;
        }

        #endregion

        #region  - 事件 -

        protected override void OnLoad(EventArgs e)
        {
            if (!DesignMode)
            {
                //设置系统菜单（在不同的地方效果不一样，放在构造函数中窗体就不在屏幕中间启动了）
                Win32.SetWindowLong(Handle, -16, Win32.WS_SYSMENU);
            }

            UpdateFunctionButtonLocation();

            MaximumSize = new Size(Screen.PrimaryScreen.WorkingArea.Width + 10,
                                                  Screen.PrimaryScreen.WorkingArea.Height + 10);

            //设置一个隐藏的窗体用户拖动窗体大小时候产生虚线
            //frmResize = new FormHideenResize(this);
            //frmResize.Show();

            base.OnLoad(e);
        }

        protected override void OnResize(EventArgs e)
        {
            //透明状态下
            if (!DesignMode && EnableTransparent)
            {
                if (currentBitmap == null)
                {
                    //此方法在构造函数之前执行，且此if区域的代码只在启动的时候执行一次

                    ContentBackColorStart = Color.FromArgb(175, Color.Black);
                    ContentBackColorEnd = Color.FromArgb(175, Color.Black);
                    ContentTopBorderColor = Color.Black;
                    ContentBottomBorderColor = Color.Black;
                }

                if (currentBitmap != null)
                {
                    currentBitmap.Dispose();
                }
                currentBitmap = new Bitmap(Width, Height, PixelFormat.Format32bppArgb);
                using (Graphics g = GetNewGraphics)
                {
                    Draw(g);
                }
            }
            else if (!EnableTransparent)
            {
                //设置圆角
                Region = new Region(DrawRoundRect(ClientRectangle, BorderRadius.LeftTop, BorderRadius.RightTop, BorderRadius.RightBottom, BorderRadius.LeftBottom));
            }

            UpdateFunctionButtonLocation();

            base.OnResize(e);
        }

        protected override CreateParams CreateParams
        {
            get
            {
                if (DesignMode || !EnableTransparent)
                {
                    return base.CreateParams;
                }

                CreateParams cp = base.CreateParams;
                cp.ExStyle |= 0x00080000; // This form has to have the WS_EX_LAYERED extended style
                return cp;
            }
        }

        void btnMax_Click(object sender, EventArgs e)
        {
            FormMax();
        }

        void btnMin_Click(object sender, EventArgs e)
        {
            FormMin();
        }

        void btnClose_Click(object sender, EventArgs e)
        {
            FormClose();
        }

        void btnClose_Paint(object sender, PaintEventArgs e)
        {
            int size = 8;

            Rectangle bounds = new Rectangle();
            /*这里的e.ClipRectangle.X 一定要加上去，否则在透明模式下
              x就会画到窗体左上角去 
             */
            bounds.X = e.ClipRectangle.X + (btnClose.Width - size) / 2;
            bounds.Y = e.ClipRectangle.Y + (btnClose.Height - size) / 2;
            bounds.Width = size;
            bounds.Height = size;
            Rectangle paintRect = CalculateZoomRectangle(bounds, new Size(5, 5));

            Graphics g = e.Graphics;
            Pen pen = new Pen(Color.FromArgb(220, Color.White), 2);
            g.DrawLine(pen, new Point(paintRect.X, paintRect.Y), new Point(paintRect.X + paintRect.Width, paintRect.Y + paintRect.Height));
            g.DrawLine(pen, new Point(paintRect.X + paintRect.Width, paintRect.Y), new Point(paintRect.X, paintRect.Y + paintRect.Height));
        }

        void btnMax_Paint(object sender, PaintEventArgs e)
        {
            int width = 8;
            int height = 8;

            Rectangle bounds = new Rectangle();
            bounds.X = e.ClipRectangle.X + (btnMax.Width - width) / 2;
            bounds.Y = e.ClipRectangle.Y + (btnMax.Height - height) / 2;
            bounds.Width = width;
            bounds.Height = height;
            Rectangle paintRect = CalculateZoomRectangle(bounds, new Size(5, 5));

            Graphics g = e.Graphics;
            g.DrawRectangle(new Pen(Color.FromArgb(220, Color.White), 2), paintRect);
        }

        void btnMin_Paint(object sender, PaintEventArgs e)
        {
            int width = 10;

            int y = e.ClipRectangle.Y + btnMax.Height / 2;
            int startX = e.ClipRectangle.X + btnMax.Width / 2 - width / 2;
            int endX = e.ClipRectangle.X + btnMax.Width / 2 + width / 2 + 2;

            Graphics g = e.Graphics;
            Point start = new Point(startX, y);
            Point end = new Point(endX, y);
            g.DrawLine(new Pen(Color.FromArgb(220, Color.White), 2), start, end);
        }

        private void FormBase_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (MaximizeBox)
            {
                Rectangle topRect = new Rectangle(0, 0, Width, TitleHeight);
                if (topRect.Contains(e.Location))  //在标题栏双击
                {
                    //这里直接调用函数，防止子类maxbutton被重写这里反应不出来
                    FormMax();
                }
            }
        }

        protected override void OnMouseMove(MouseEventArgs e)
        {
            #region 拖动边框大小

            if (WindowState != FormWindowState.Maximized && SizeAble) //非最大化状态且可调整
            {
                #region 大小限定判断

                if (ClientRectangle.Width > MaximumSize.Width)
                {
                    Width = MaximumSize.Width;
                    return;
                }

                if (ClientRectangle.Height > MaximumSize.Height)
                {
                    Height = MaximumSize.Height;
                    return;
                }

                if (ClientRectangle.Width < MinimumSize.Width)
                {
                    Width = MinimumSize.Width;
                    return;
                }

                if (ClientRectangle.Height < MinimumSize.Height)
                {
                    Height = MinimumSize.Height;
                    return;
                }

                #endregion


                if (e.X > 4 && e.X < Width - 4 && e.Y >= Height - 4) //拖动下边框
                {
                    Cursor.Current = Cursors.SizeNS;
                    if (e.Button == MouseButtons.Left)
                    {
                        Win32.ReleaseCapture();
                        Win32.SendMessage(Handle, 274, 61440 + 6, 0);
                        //  Win32.SendMessage(frmResize.Handle, 274, 61440 + 7, 0);
                        //  frmResize.Invalidate();
                        return;
                    }
                }
                if (e.X <= 4 && e.Y >= Height - 4) //拖动左下角
                {
                    Cursor.Current = Cursors.SizeNESW;
                    if (e.Button == MouseButtons.Left)
                    {
                        Win32.ReleaseCapture();
                        Win32.SendMessage(Handle, 274, 61440 + 7, 0);
                        return;
                    }
                }
                if (e.X >= Width - 4 && e.Y >= Height - 4) //拖动右下角变化大小
                {
                    Cursor.Current = Cursors.SizeNWSE;
                    if (e.Button == MouseButtons.Left)
                    {
                        Win32.ReleaseCapture();
                        Win32.SendMessage(Handle, 274, 61440 + 8, 0);
                        return;
                    }
                }
                if (e.X >= Width - 4 && e.Y > 4 && e.Y < Height - 4) //拖动右边框
                {
                    Cursor.Current = Cursors.SizeWE;
                    if (e.Button == MouseButtons.Left)
                    {
                        Win32.ReleaseCapture();
                        Win32.SendMessage(Handle, 274, 61440 + 2, 0);
                        return;
                    }
                }
                if (e.X <= 4 && e.Y > 4 && e.Y < Height - 4) //拖动左边框
                {
                    Cursor.Current = Cursors.SizeWE;
                    if (e.Button == MouseButtons.Left)
                    {
                        Win32.ReleaseCapture();
                        Win32.SendMessage(Handle, 274, 61440 + 7, 0);
                        return;
                    }
                }
                if (e.X <= 4 && e.Y <= 4) //拖动左上角
                {
                    Cursor.Current = Cursors.SizeNWSE;
                    if (e.Button == MouseButtons.Left)
                    {
                        Win32.ReleaseCapture();
                        Win32.SendMessage(Handle, 274, 61440 + 4, 0);
                        return;
                    }
                }
                if (e.X > 4 && e.X < Width - 4 && e.Y <= 4) //拖动上边
                {
                    Cursor.Current = Cursors.SizeNS;
                    if (e.Button == MouseButtons.Left)
                    {
                        Win32.ReleaseCapture();
                        Win32.SendMessage(Handle, 274, 61440 + 3, 0);
                        return;
                    }
                }
                if (e.X >= Width - 4 && e.Y <= 4) //拖动右上角
                {
                    Cursor.Current = Cursors.SizeNESW;
                    if (e.Button == MouseButtons.Left)
                    {
                        Win32.ReleaseCapture();
                        Win32.SendMessage(Handle, 274, 61440 + 5, 0);
                        return;
                    }
                }
            }

            #endregion

            #region 移动窗体

            if (canMove && e.Button == MouseButtons.Left
               && WindowState != FormWindowState.Maximized
               && TitleRectangle.Contains(e.Location)) //拖动窗体
            {
                Win32.ReleaseCapture();
                Win32.SendMessage(Handle, 274, 61440 + 9, 0);
                return;
            }
            #endregion

            base.OnMouseMove(e);
        }

        #endregion

        #region - 方法 -

        /// <summary>
        /// 在子类重写此方法的时候，一定要注意
        /// 不要忘记将base.Draw(g)放在最后调用
        /// </summary>
        /// <param name="g"></param>
        protected virtual void Draw(Graphics g)
        {
            if (EnableTransparent)
            {
                List<Control> transControls = new List<Control>();
                FindAllTranControls(this, transControls);
                foreach (Control control in transControls)
                {
                    //TODO:有可能需要enhancement
                    var transControl = control as ITransparent;
                    if (transControl != null) transControl.Draw(currentBitmap, control.Bounds);
                }

                SetBitmap();
            }
        }

        /// <summary>
        /// 如果想改变关闭按钮点击行为，重写此方法
        /// </summary>
        protected virtual void FormClose()
        {
            Close();
        }

        protected virtual void FormMin()
        {
            WindowState = FormWindowState.Minimized;
        }

        protected virtual void FormMax()
        {
            if (WindowState == FormWindowState.Normal)
            {
                WindowState = FormWindowState.Maximized;
            }
            else
            {
                WindowState = FormWindowState.Normal;
            }
        }

        /// <summary>
        /// 绘制圆角矩形
        /// </summary>
        protected GraphicsPath DrawRoundRect(int x, int y, int width, int height, int radius)
        {
            return DrawRoundRect(x, y, width, height, radius, radius, radius, radius);
        }

        /// <summary>
        /// 绘制圆角矩形
        /// </summary>
        protected GraphicsPath DrawRoundRect(Rectangle rect, int radius)
        {
            return DrawRoundRect(rect.X, rect.Y, rect.Width, rect.Height, radius);
        }

        /// <summary>
        /// 绘制圆角矩形（提供四个角自定义角度）
        /// </summary>
        /// <param name="r"></param>
        /// <param name="r1">左上角角度</param>
        /// <param name="r2">右上角角度</param>
        /// <param name="r3">右下角角度</param>
        /// <param name="r4">左下角角度</param>
        /// <returns></returns>
        protected GraphicsPath DrawRoundRect(Rectangle r, int r1, int r2, int r3, int r4)
        {
            float x = r.X, y = r.Y, w = r.Width, h = r.Height;
            GraphicsPath rr = new GraphicsPath();
            rr.AddBezier(x, y + r1, x, y, x + r1, y, x + r1, y);
            rr.AddLine(x + r1, y, x + w - r2, y);
            rr.AddBezier(x + w - r2, y, x + w, y, x + w, y + r2, x + w, y + r2);
            rr.AddLine(x + w, y + r2, x + w, y + h - r3);
            rr.AddBezier(x + w, y + h - r3, x + w, y + h, x + w - r3, y + h, x + w - r3, y + h);
            rr.AddLine(x + w - r3, y + h, x + r4, y + h);
            rr.AddBezier(x + r4, y + h, x, y + h, x, y + h - r4, x, y + h - r4);
            rr.AddLine(x, y + h - r4, x, y + r1);
            return rr;
        }

        /// <summary>
        /// 绘制圆角矩形（提供四个角自定义角度）
        /// </summary>
        protected GraphicsPath DrawRoundRect(float x, float y, float w, float h, int r1, int r2, int r3, int r4)
        {
            GraphicsPath rr = new GraphicsPath();
            rr.AddBezier(x, y + r1, x, y, x + r1, y, x + r1, y);
            rr.AddLine(x + r1, y, x + w - r2, y);
            rr.AddBezier(x + w - r2, y, x + w, y, x + w, y + r2, x + w, y + r2);
            rr.AddLine(x + w, y + r2, x + w, y + h - r3);
            rr.AddBezier(x + w, y + h - r3, x + w, y + h, x + w - r3, y + h, x + w - r3, y + h);
            rr.AddLine(x + w - r3, y + h, x + r4, y + h);
            rr.AddBezier(x + r4, y + h, x, y + h, x, y + h - r4, x, y + h - r4);
            rr.AddLine(x, y + h - r4, x, y + r1);
            return rr;
        }

        /// <summary>
        /// 得到两种颜色的过渡色（1代表开始色，100表示结束色）
        /// </summary>
        /// <param name="c">开始色</param>
        /// <param name="c2">结束色</param>
        /// <param name="value">需要获得的度</param>
        /// <returns></returns>
        protected Color GetIntermediateColor(Color c, Color c2, int value)
        {
            float pc = value * 1.0F / 100;

            int ca = c.A, cr = c.R, cg = c.G, cb = c.B;
            int c2a = c2.A, c2r = c2.R, c2g = c2.G, c2b = c2.B;

            int a = (int)Math.Abs(ca + (ca - c2a) * pc);
            int r = (int)Math.Abs(cr - ((cr - c2r) * pc));
            int g = (int)Math.Abs(cg - ((cg - c2g) * pc));
            int b = (int)Math.Abs(cb - ((cb - c2b) * pc));

            if (a > 255) { a = 255; }
            if (r > 255) { r = 255; }
            if (g > 255) { g = 255; }
            if (b > 255) { b = 255; }

            return (Color.FromArgb(a, r, g, b));
        }

        /// <summary>
        /// 获得关闭按钮的矩形区域
        /// </summary>
        /// <returns></returns>
        protected Point GetCloseButtonLocation()
        {
            Point point = new Point();
            point.Y = functionBtnMarginTop;
            if (ShowCloseButton)
            {
                point.X = Width - btnClose.Width - FunctionBtnMarginRight;
            }
            else
            {
                point.Y = -50; //隐藏
            }
            return point;
        }

        protected Point GetMaxButtonLocation()
        {
            Point p = new Point();
            p.Y = functionBtnMarginTop;
            Point closeButtonLocation = GetCloseButtonLocation();
            if (MaximizeBox && ShowCloseButton)
            {
                p.X = closeButtonLocation.X - btnMax.Width + 1/*交界部分公用一个外边框*/;
            }
            else if (MaximizeBox && !ShowCloseButton)
            {
                p.X = Width - btnMax.Width - FunctionBtnMarginRight;
            }
            else if (!MaximizeBox)
            {
                p.Y = -50;
            }
            return p;
        }

        protected Point GetMinButtonLocation()
        {
            Point p = new Point();
            p.Y = functionBtnMarginTop;
            Point maxButtonLocation = GetMaxButtonLocation();
            Point closeButtonLocation = GetCloseButtonLocation();

            if (MinimizeBox && MaximizeBox)
            {
                p.X = maxButtonLocation.X - btnMin.Width + 1/*交界部分公用一个外边框*/;
            }
            else if (MinimizeBox && !MaximizeBox && ShowCloseButton)
            {
                p.X = closeButtonLocation.X - btnMin.Width + 1;
            }
            else if (MinimizeBox && !MaximizeBox && !ShowCloseButton)
            {
                p.X = Width - btnMin.Width - FunctionBtnMarginRight;
            }
            else if (!MinimizeBox)
            {
                p.Y = -50;
            }
            return p;
        }

        protected void UpdateFunctionButtonLocation()
        {
            btnClose.Location = GetCloseButtonLocation();
            btnMin.Location = GetMinButtonLocation();
            btnMax.Location = GetMaxButtonLocation();
        }

        /// <summary>
        /// 将当前的currentBitmap画到分层窗口中
        /// </summary>
        protected void SetBitmap()
        {
            if (currentBitmap != null)
            {
                SetBitmap(currentBitmap, 255);
            }
        }

        protected void SetBitmap(Bitmap bitmap, byte opacity)
        {
            if (bitmap.PixelFormat != PixelFormat.Format32bppArgb)
                throw new ApplicationException("The bitmap must be 32ppp with alpha-channel.");

            // The ideia of this is very simple,
            // 1. Create a compatible DC with screen;
            // 2. Select the bitmap with 32bpp with alpha-channel in the compatible DC;
            // 3. Call the UpdateLayeredWindow.

            IntPtr screenDc = Win32.GetDC(IntPtr.Zero);
            IntPtr memDc = Win32.CreateCompatibleDC(screenDc);
            IntPtr hBitmap = IntPtr.Zero;
            IntPtr oldBitmap = IntPtr.Zero;

            try
            {
                hBitmap = bitmap.GetHbitmap(Color.FromArgb(0)); // grab a GDI handle from this GDI+ bitmap
                oldBitmap = Win32.SelectObject(memDc, hBitmap);

                var size = new Win32.Size(bitmap.Width, bitmap.Height);
                var pointSource = new Win32.Point(0, 0);
                var topPos = new Win32.Point(Left, Top);
                var blend = new Win32.BLENDFUNCTION();
                blend.BlendOp = Win32.AC_SRC_OVER;
                blend.BlendFlags = 0;
                blend.SourceConstantAlpha = opacity;
                blend.AlphaFormat = Win32.AC_SRC_ALPHA;

                Win32.UpdateLayeredWindow(Handle, screenDc, ref topPos, ref size, memDc, ref pointSource, 0, ref blend,
                                          Win32.ULW_ALPHA);
            }
            finally
            {
                Win32.ReleaseDC(IntPtr.Zero, screenDc);
                if (hBitmap != IntPtr.Zero)
                {
                    Win32.SelectObject(memDc, oldBitmap);
                    //Windows.DeleteObject(hBitmap); // The documentation says that we have to use the Windows.DeleteObject... but since there is no such method I use the normal DeleteObject from Win32 GDI and it's working fine without any resource leak.
                    Win32.DeleteObject(hBitmap);
                }
                Win32.DeleteDC(memDc);
            }
        }

        /// <summary>
        /// 更新窗体上的某个控件
        /// 此方法一般在窗体上的某个控件需要更新时由对应的控件调用
        /// </summary>
        /// <param name="control"></param>
        public void UpdateControl(Control control)
        {
            if (control is ITransparent)
            {
                var tranControl = control as ITransparent;
                tranControl.Draw(currentBitmap, control.Bounds);
                SetBitmap();
            }
        }

        /// <summary>
        /// 找到某个控件下所有的子控件
        /// </summary>
        /// <param name="control"></param>
        /// <param name="controls"></param>
        protected void FindAllTranControls(Control control, List<Control> controls)
        {
            if (control.HasChildren)
            {
                foreach (Control c in control.Controls)
                {
                    if (c is ITransparent)
                    {
                        controls.Add(c);
                    }
                    FindAllTranControls(c, controls);
                }
            }
        }

        /// <summary>
        /// 当开启透明效果时，更新窗体上所有控件
        /// </summary>
        public void UpdateAllControl()
        {
            if (EnableTransparent)
            {
                Draw(GetNewGraphics);
            }
        }


        protected void DrawBackground(Graphics g, Rectangle rect, Color backColorStart, Color backColorEnd,
                                    BorderRadiu radius)
        {
            if (rect.Width == 0 || rect.Height == 0)
            {
                return;
            }

            using (var backgroundBrush = new LinearGradientBrush(rect,
                                                                 Color.FromArgb(TransparentAlpha, backColorStart), Color.FromArgb(TransparentAlpha, backColorEnd),
                                                                 LinearGradientMode.Vertical))
            {
                g.FillPath(backgroundBrush, DrawRoundRect(rect.X,
                                                          rect.Y,
                                                          rect.Width,
                                                          rect.Height, radius.LeftTop, radius.RightTop,
                                                          radius.RightBottom, radius.LeftBottom));
            }
        }

        /// <summary>
        /// 计算在给定的一个矩形框中绘画给定大小矩形的位置（按缩放）
        /// </summary>de
        /// <param name="bounds"></param>
        /// <param name="trueSize"></param>
        /// <returns></returns>
        protected Rectangle CalculateZoomRectangle(Rectangle bounds, Size trueSize)
        {
            Rectangle rectangle = bounds;

            float num1 = bounds.Width / (float)trueSize.Width;
            float num2 = bounds.Height / (float)trueSize.Height;
            if (num1 < (double)num2)
            {
                rectangle.Width = bounds.Width;
                rectangle.Height = (int)(trueSize.Height * (double)num1 + 0.5);
                if (bounds.Y >= 0)
                {
                    rectangle.Y += (bounds.Height - rectangle.Height) / 2;
                }
            }
            else
            {
                rectangle.Height = bounds.Height;
                rectangle.Width = (int)(trueSize.Width * (double)num2 + 0.5);
                if (bounds.X >= 0)
                {
                    rectangle.X += (bounds.Width - rectangle.Width) / 2;
                }
            }


            return rectangle;
        }

        #endregion
    }
}
